package io.broker.api.client.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import io.broker.api.client.domain.account.*;
import okhttp3.*;
import org.apache.logging.log4j.util.Strings;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

public class BrokerApiCustomService {

    private static final OkHttpClient client = new OkHttpClient.Builder()
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .connectTimeout(10, TimeUnit.SECONDS)
            .pingInterval(10, TimeUnit.SECONDS) // websocket 轮训间隔
            .build();

    private static final ObjectMapper objectMapper = new ObjectMapper();

    private final String token;

    private final String cookie;

    private final String accountId;

    public BrokerApiCustomService(String token, String cookie, String accountId) {
        this.token = token;
        this.cookie = cookie;
        this.accountId = accountId;
    }

    public NewOrderResponse newOrder(String symbol, OrderSide side, BigDecimal quantity, BigDecimal price) {

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");

        RequestBody body =
                RequestBody.create(
                        mediaType,
                        "type=limit&side="
                                + side.name()
                                + "&price="
                                + price
                                + "&quantity="
                                + quantity
                                + "&symbol_id="
                                + symbol
                                + "&order_time=0&client_order_id="
                                + System.currentTimeMillis()
                                + "&account_id=" + accountId + "&exchange_id=665");

        Request request = new Request.Builder()
                .url("https://www.beex.one/api/order/create?c_token=" + token)
                .post(body)
                .addHeader("Cookie", cookie)
                .addHeader("Origin", "https://www.beex.one")
                .addHeader("Accept-Encoding", "deflate, br")
                .addHeader("accept-language", "zh-cn")
                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")
                .addHeader("content-type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "*/*")
                .addHeader("Referer", "https://www.beex.one/exchange/665/AT/USDT")
                .addHeader("x-requested-with", "XMLHttpRequest")
                .addHeader("Connection", "keep-alive")
                .addHeader("cache-control", "no-cache")
                .build();

        try (Response response = client.newCall(request).execute()) {
            String responseValue = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseValue, NewOrderResponse.class);

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public void cancelOrder(String client_order_id, String order_id) {

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body =
                RequestBody.create(
                        mediaType,
                        "client_order_id="
                                + client_order_id
                                + "&account_id=" + accountId + "&order_id="
                                + order_id
                                + "&i=0");
        Request request =
                new Request.Builder()
                        .url("https://www.beex.one/api/order/cancel?c_token=" + token)
                        .post(body)
                        .addHeader("Cookie", cookie)
                        .addHeader("Origin", "https://www.beex.one")
                        .addHeader("Accept-Encoding", "deflate, br")
                        .addHeader("accept-language", "zh-cn")
                        .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")
                        .addHeader("content-type", "application/x-www-form-urlencoded")
                        .addHeader("Accept", "*/*")
                        .addHeader("Referer", "https://www.beex.one/exchange/665/AT/USDT")
                        .addHeader("x-requested-with", "XMLHttpRequest")
                        .addHeader("Connection", "keep-alive")
                        .addHeader("cache-control", "no-cache")
                        .build();

        try (Response response = client.newCall(request).execute()) {
            String responseValue = Objects.requireNonNull(response.body()).string();
            objectMapper.readValue(responseValue, CancelOrderResponse.class);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public List<Order> getOpenOrders() {
        Request request = new Request.Builder()
                .url("https://www.beex.one/api/order/open_orders?c_token=" + token + "&account_id="+ accountId + "&from_order_id=0&limit=20")
                .get()
                .addHeader("Cookie", cookie)
                .addHeader("Origin", "https://www.beex.one")
                .addHeader("Accept-Encoding", "deflate, br")
                .addHeader("accept-language", "zh-cn")
                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")
                .addHeader("content-type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "*/*")
                .addHeader("Referer", "https://www.beex.one/exchange/665/AT/USDT")
                .addHeader("x-requested-with", "XMLHttpRequest")
                .addHeader("Connection", "keep-alive")
                .addHeader("cache-control", "no-cache")
                .build();

        try (Response response = client.newCall(request).execute()) {
            String responseValue = Objects.requireNonNull(response.body()).string();
            if ( Strings.isBlank(responseValue)) {
                return Lists.newArrayList();
            }
            Order[] beeOrders = objectMapper.readValue(responseValue, Order[].class);
            return Arrays.asList(beeOrders);

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public List<BeeOrder> queryBeeOrders(String end_trade_id) {

        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://www.beex.one/api/order/my_trades?c_token=" + token + "&account_id=" + accountId + "&limit=30000&end_trade_id=" + end_trade_id)
                .get()
                .addHeader("Cookie", cookie)
                .addHeader("Accept-Encoding", "deflate, br")
                .addHeader("accept-language", "zh-cn")
                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")
                .addHeader("content-type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "*/*")
                .addHeader("Referer", "https://www.beex.one/order")
                .addHeader("x-requested-with", "XMLHttpRequest")
                .addHeader("Connection", "keep-alive")
                .addHeader("Cache-Control", "no-cache")
                .addHeader("Postman-Token", "21fff1a3-dcb9-43ba-9f3c-c4af656e4758,220d0666-5c58-4b8e-aaed-c769ca427cf4")
                .addHeader("Host", "www.beex.one")
                .addHeader("cache-control", "no-cache")
                .build();

        try (Response response = client.newCall(request).execute()) {
            String responseBody = response.body().string();

            BeeOrder[] beeOrders = objectMapper.readValue(responseBody, BeeOrder[].class);

            return Arrays.asList(beeOrders);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
